from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from django.contrib.auth.hashers import check_password
from rest_framework_jwt.utils import jwt_payload_handler,jwt_encode_handler
from rest_framework.pagination import PageNumberPagination

from .models import *
from .task import send_message
from .serializer import *

import random,redis,time
from datetime import datetime

# Create your views here.
# 发送短信
class SmsAPIView(APIView):
    def post(self,request):
        mobile = request.data.get('mobile')

        if not all([mobile,]):
            return Response({'code':400,'msg':'数据不完整'})

        # 生成一个短信验证码
        sms_code = "%d"%random.randint(10000,99999)

        # 储存短信验证码
        redis_conn = redis.Redis(password="123456",db=3)
        redis_conn.set(mobile,sms_code,ex=300)

        # 请求容联云 发送短信
        # res = send_message.delay(sms_code,mobile)
        res = send_message(sms_code,mobile)

        return Response({'code':200,'msg':'短信已发送，请注意查收'})

# 登录
class LoginCountAPIView(APIView):
    def post(self,request):
        username = request.data.get("username")
        password = request.data.get("password")
        mobile = request.data.get("mobile")
        code = request.data.get("code")

        # if not all([username,password,mobile,code]):
        #     return Response({'code':400,'msg':'数据不完整'})

        user = User.objects.filter(username=username).first()
        redis_conn = redis.Redis(password="123456",db=3)
        if user:
            # 用户存在(对password进行相同算法的加密对比)
            if check_password(password,user.password):
                if user.is_active and user.is_staff:
                    token = self.get_token(user)
                    user.last_login = datetime.now()
                    user.save()
                    return Response({"code": "200", "msg": "登录成功，进入首页",
                                     "username":user.username,"uid":user.id,"token":token})
                else:
                    return Response({"code":"206","msg":"没有管理员权限"})
            else:
                # 密码不正确，重置密码
                if mobile and code:
                    validate_sms_code = self.validate_code(redis_conn,mobile,code)
                    # 校验验证码
                    if validate_sms_code:
                        # 重置密码
                        user.set_password(password)
                        user.save()
                        return Response({"code": "207", "msg": "密码已重置"})
                    else:
                        return Response({"code": "204", "msg": "验证码过期或者错误"})
                else:
                    return Response({"code":"205","msg":"用户名或密码错误"})
        else:
            # 用户不存在
            validate_sms_code = self.validate_code(redis_conn,mobile,code)
            if validate_sms_code:
                # 验证码通过，保存用户信息
                User.objects.create_user(username=username,password=password,phone=mobile)
                user.last_login = datetime.now()
                print('时间>>>>>>>>>>>>>>>>',datetime.now())
                user.save()
                return Response({"code": "201", "msg": "注册成功，需申请管理员权限"})
            else:
                return Response({"code": "204", "msg": "验证码过期或者错误"})


    @staticmethod
    def get_token(user):
        """
        :param user: 登录的用户对象
        :return token: 返回jwt token
        """
        payload = jwt_payload_handler(user)

        # 编码payload，生成token
        token = jwt_encode_handler(payload)
        return token

    @staticmethod
    def validate_code(redis_conn,mobile,code):
        """
        :param redis_conn: redis连接对象
        :param mobile: 用户的手机号，用于获取redis中的验证码
        :param code: 前端传来的验证码
        :return Boolean:
        """
        stored_code = redis_conn.get(mobile)
        # redis取出来的是字节串，decode解码转换成字符串
        if stored_code and stored_code.decode() == code:
            return True
        else:
            return False

# 统计总人数
class CountUserAPIView(APIView):
    def get(self,request):
        total_count = User.objects.all().count()
        return Response({'code':200,'total_count':total_count})

# 统计日增用户
class DayIncrementAPIView(APIView):
    def get(self,request):
        date = time.strftime("%Y-%m-%d")
        # date_joined 加入时间
        # __contains 包含
        total_count = User.objects.filter(date_joined__contains=date).count()
        return Response({'code':200,'total_count':total_count})

# 统计日活用户
class DayLiveAPIView(APIView):
    def get(self,request):
        date_ = time.strftime("%Y-%m-%d")
        total_count = User.objects.filter(last_login__contains=date_).count()
        return Response({'code': 200, 'total_count': total_count})


# 分页器
class MyPagination(PageNumberPagination):
    page_size = 2
    max_page_size = 3
    page_query_param = 'page'
    page_size_query_param = 'pagesize'

# 用户管理的视图集
class UserInfoViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSer
    pagination_class = MyPagination
    lookup_field = 'pk'
    lookup_url_kwarg = 'pk'

    def update(self, request, *args, **kwargs):
        try:
            user = self.get_object()
            user.username = request.data.get('username')
            user.phone = request.data.get('phone')
            user.email = request.data.get('email')
            user.set_password(request.data.get('password'))
            user.save()
        except:
            return Response({'code':400,'msg':'更新用户数据,后端报错！'})

        return Response({'code':200,'msg':'更新用户成功！'})

    def create(self, request, *args, **kwargs):
        try:
            User.objects.create_user(**request.data)
        except:
            return Response({'code': 500, 'msg': '创建用户报错'})
        return Response({'code': 200, 'msg': '添加用户成功'})


# 上传用户头像的视图
from rest_framework_jwt.utils import jwt_encode_handler
from jwt.exceptions import ExpiredSignatureError,DecodeError
from django.conf import settings
import os


class UploadImageView(APIView):
    def post(self,request):
        # 1.获取前端数据
        # token = request.get.data('token')
        file = request.data.get('file')

        # 2.验证token
        # try:
        #     jwt_encode_handler(token)
        # except ExpiredSignatureError:
        #     return Response({'msg':'口令过期','code':401})
        # except DecodeError:
        #     return Response({'msg': '口令不正确', 'code': 401})

        # 3.验证通过，可以上传图片
        static_path = 'static/images/users'
        abs_path = os.path.join(settings.BASE_DIR,static_path)
        file_name = file.name

        # 4.判断目录是否存在
        if not os.path.exists(abs_path):
            os.makedirs(abs_path)

        # 5.保存图片
        user_path = os.path.join(abs_path,file_name)

        with open(user_path,'wb') as f:
            f.write(file.file.read())

        return Response({
            'code':200,
            'msg':'上传图片成功',
            'static_path':static_path,
            })


# 增加用户图片的视图集
class UserImageView(ModelViewSet):
    queryset = UserImage.objects.all()
    serializer_class = UserImageSer
    lookup_field = 'pk'
    lookup_url_kwarg = 'pk'

    def create(self, request, *args, **kwargs):
        avatar = request.data.get('avatar')
        user_id = request.data.get('user_id')

        results = UserImage.objects.filter(avatar=avatar,user_id=user_id)

        if results:
            return Response({'msg':'该头像已被添加','code':400})
        else:
            try:
                UserImage.objects.create(avatar=avatar,user_id=user_id)
                return Response({'msg': '添加成功', 'code': 201})
            except:
                return Response({'msg': '添加失败'})



